/*
 * $RCSfile: Changeable.java,v $$
 * $Revision: 1.1 $
 * $Date: 2014-03-01 $
 *
 * Copyright (C) 2008 Skin, Inc. All rights reserved.
 *
 * This software is the proprietary information of Skin, Inc.
 * Use is subject to license terms.
 */
package com.skin.webcat.database;

import java.util.ArrayList;
import java.util.List;

import com.skin.webcat.util.Sql;

/**
 * <p>Title: Changeable</p>
 * <p>Description: </p>
 * <p>Copyright: Copyright (c) 2006</p>
 * @author xuesong.net
 * @version 1.0
 */
public abstract class Changeable {
    /**
     * @param args
     * @return String
     */
    public static String validate(List<?> ... args) {
        if(args != null && args.length > 0) {
            for(List<?> changeList : args) {
                for(Object item : changeList) {
                    Changeable changeable = (Changeable)item;
                    String message = changeable.validate();

                    if(message != null) {
                        return message;
                    }
                }
            }
        }
        return null;
    }

    /**
     * @param args
     */
    public void apply(ChangeValue ... args) {
        if(args != null && args.length > 0) {
            for(ChangeValue changeValue : args) {
                changeValue.apply();
            }
        }
    }

    /**
     * @param tableName
     * @return String
     */
    public abstract String getCreateSql(String tableName);

    /**
     * @param tableName
     * @return String
     */
    public abstract String getAlterSql(String tableName);

    /**
     * @return boolean
     */
    public abstract boolean modified();

    /**
     * @return String
     */
    public abstract String validate();

    /**
     * apply
     */
    public void apply() {
        throw new UnsupportedOperationException("method 'apply' is not supported!");
    }

    /**
     * @param args
     * @return boolean
     */
    public boolean modified(ChangeValue ... args) {
        if(args == null || args.length < 1) {
            return false;
        }

        for(ChangeValue changeValue : args) {
            if(changeValue.modified()) {
                return true;
            }
        }
        return false;
    }

    /**
     * @param changeValue
     * @return boolean
     */
    public boolean validate(ChangeValue changeValue) {
        if(changeValue.notEmpty(changeValue.getOldValue()) && !Sql.isSqlIdentifier(changeValue.getOldValue())) {
            return false;
        }

        if(changeValue.notEmpty(changeValue.getNewValue()) && !Sql.isSqlIdentifier(changeValue.getNewValue())) {
            return false;
        }
        return true;
    }

    /**
     * @param source
     * @param seperator
     * @return boolean
     */
    public boolean validate(String source, String seperator) {
        String[] values = this.split(source, seperator, true, true);

        for(int i = 0; i < values.length; i++) {
            if(!Sql.isSqlIdentifier(values[i])) {
                return false;
            }
        }
        return true;
    }

    /**
     * @param source
     * @param length
     * @param pad
     * @return String
     */
    public String padding(String source, int length, String pad) {
        StringBuilder buffer = new StringBuilder(source);
        int count = source.length();

        while(count < length) {
            buffer.append(pad);
            count += pad.length();
        }

        String result = buffer.toString();

        if(result.length() > length) {
            return result.substring(0, length);
        }
        return result;
    }

    /**
     * @param source
     * @param seperator
     * @param trim
     * @param ignoreWhitespace
     * @return String[]
     */
    public String[] split(String source, String seperator, boolean trim, boolean ignoreWhitespace) {
        if(source == null) {
            return new String[0];
        }
        
        int i = 0;
        int j = 0;
        String s = null;
        List<String> list = new ArrayList<String>();

        while((j = source.indexOf(seperator, i)) > -1) {
            if(j > i) {
                s = source.substring(i, j);

                if(trim) {
                    s = s.trim();
                }

                if(!ignoreWhitespace || s.length() > 0) {
                    list.add(s);
                }
            }
            i = j + seperator.length();
        }

        if(i < source.length()) {
            s = source.substring(i);

            if(trim) {
                s = s.trim();
            }

            if(!ignoreWhitespace || s.length() > 0) {
                list.add(s);
            }
        }
        String[] result = new String[list.size()];
        return list.toArray(result);
    }
}
